package local_server

// 导入必要的包
import (
	"Lunar-Astral-API/local_server/config" // 项目配置相关包
	"Lunar-Astral-API/local_server/utils"  // 工具函数包
	"fmt"                                  // 用于格式化输入输出
	"log"                                  // 用于日志记录
	"net"                                  // 用于网络操作
	"net/http"                             // 用于构建HTTP服务器
	"time"                                 // 用于时间相关操作
)

// startServer 启动HTTP服务器
func startServer() *http.Server {
	// 创建一个新的 HTTP 服务器实例
	server := &http.Server{}
	// 启动服务器监听
	go startServerListener(server)
	return server
}

// startServerListener 启动服务器监听循环
func startServerListener(server *http.Server) {
	// 打印启动服务器的日志信息
	log.Printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-")
	// 定义最大尝试次数
	const maxAttempts = 10
	// 尝试启动服务器
	if !attemptServerStart(server, maxAttempts) {
		log.Fatalf("DEV服务器[ERROR] -> 无可用端口")
	}
}

// attemptServerStart 尝试启动服务器，最多尝试指定次数
func attemptServerStart(server *http.Server, maxAttempts int) bool {
	for range maxAttempts {
		if tryStartServerOnPort(server) {
			return true
		}
		*config.SystemUrlPort++
	}
	return false
}

// tryStartServerOnPort 尝试在指定端口上启动服务器
func tryStartServerOnPort(server *http.Server) bool {
	// 尝试在指定端口上创建 TCP 监听器
	listener, err := net.Listen("tcp", fmt.Sprintf(":%d", *config.SystemUrlPort))
	if err != nil {
		log.Printf("DEV服务器[ERROR] -> %d 端口被占用\n", *config.SystemUrlPort)
		return false
	}
	// 服务器成功启动后的初始化工作
	initializeServerComponents(server)
	// 启动服务器开始监听客户端连接
	if err := server.Serve(listener); err != nil && err != http.ErrServerClosed {
		log.Fatalf("DEV服务器[ERROR] -> %v", err)
	}
	return true
}

// initializeServerComponents 初始化服务器组件
func initializeServerComponents(server *http.Server) {
	// 为服务器添加 CORS 中间件
	server.Handler = utils.CORSMiddleware(http.DefaultServeMux)
	// 启动后台任务保存链接信息
	go startBackgroundTasks()
}

// startBackgroundTasks 启动后台任务
func startBackgroundTasks() {
	// 获取本地 IP 地址
	ip, err := utils.GetLocalIP()
	if err != nil {
		log.Printf("DEV服务器[ERROR] -> %v\n", err)
		return
	}
	// 构建客户端访问的 URL
	url := utils.ClientUrl(ip)
	// 构建内部接口的 URL
	internalURL := fmt.Sprintf("http://%s:%d/v1", ip, *config.SystemUrlPort)
	// 延迟 200 毫秒，确保服务器启动完成
	time.Sleep(200 * time.Millisecond)
	// 保存链接信息
	saveLinkInformation(url, internalURL)
	// 等待 500 毫秒，确保服务器完全启动，各项资源准备就绪
	time.Sleep(500 * time.Millisecond)
	// 检查是否非开发模式，如果不是开发模式，则自动打开浏览器访问服务器
	if !*config.SystemDevMode {
		utils.OpenBrowser(url)
	}
}

// saveLinkInformation 保存链接和笔记信息
func saveLinkInformation(url, internalURL string) {
	// 保存聊天 UI 访问地址
	if saveErr := utils.SaveLinkViaHTTP(*config.SystemUrlPort, "Chat_UI", "聊天UI访问地址", url); saveErr != nil {
		log.Printf("DEV服务器[ERROR] -> %v", saveErr)
	}
	// 保存内部接口地址
	if saveErr := utils.SaveLinkViaHTTP(*config.SystemUrlPort, "IN_API", "内部接口（IN=Internal）", internalURL); saveErr != nil {
		log.Printf("DEV服务器[ERROR] -> %v", saveErr)
	}
}
